home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 406_01 / atoc / keywords.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-09  |  5.5 KB  |  220 lines

  1. /*=========================================================================
  2.  
  3.     ATOC keywords module
  4.  
  5. =========================================================================*/
  6.  
  7. #include <stdio.h>
  8. #include <ctype.h>
  9. #include "atoc.h"
  10.  
  11.  
  12. /*-------------------------------------------------------------------------
  13. keywords( fo, s ) handles ANSI keywords that do not exist in K&R C.
  14. -------------------------------------------------------------------------*/
  15. keywords( fo, s )
  16. FILE *fo;
  17. char *s;
  18. {
  19.     char *cp, *ep, *strstr();
  20.  
  21.     /* remove const keyword */
  22.     for ( cp = s; ( cp = strstr( cp, "const" ) ) != NULL; ++cp )
  23.         if ( cp == s || ! isid( *( cp - 1 ) ) )
  24.             if ( ! isid( *( cp + 5 ) ) )
  25.             {
  26.                 for ( ep = cp + 5; *ep; ++ep )
  27.                     if ( ! isspace( *ep ) )
  28.                         break;
  29.                 strcpy( cp, ep );
  30.             }
  31.  
  32.     /* translate enums into defines and ints */
  33.     if ( enumflag )
  34.         for ( cp = s; ( cp = strstr( cp, "enum" ) ) != NULL; ++cp )
  35.             if ( cp == s || ! isid( *( cp - 1 ) ) )
  36.                 if ( ! isid( *( cp + 4 ) ) )
  37.                     enumeration( fo, s );
  38.  
  39.     /* remove signed keyword */
  40.     for ( cp = s; ( cp = strstr( cp, "signed" ) ) != NULL; ++cp )
  41.         if ( cp == s || ! isid( *( cp - 1 ) ) )
  42.             if ( ! isid( *( cp + 6 ) ) )
  43.             {
  44.                 for ( ep = cp + 6; *ep; ++ep )
  45.                     if ( ! isspace( *ep ) )
  46.                         break;
  47.                 strcpy( cp, ep );
  48.             }
  49.  
  50.  
  51.     /* translate void into int */
  52.     for ( cp = s; ( cp = strstr( cp, "void" ) ) != NULL; ++cp )
  53.         if ( cp == s || ! isid( *( cp - 1 ) ) )
  54.             if ( ! isid( *( cp + 4 ) ) )
  55.             {
  56.                 if ( fplist( s, cp ) )            /* if func parm list */
  57.                     strcpy( cp, cp + 4 );        /* always remove */
  58.                 else if ( voidflag )            /* else if altering void */
  59.                 {
  60.                     strcpy( cp, cp + 4 );        /* remove */
  61.                     strins( cp, "int" );        /* replace with "int" */
  62.                 }
  63.             }
  64.  
  65.     /* remove volatile keyword */
  66.     for ( cp = s; ( cp = strstr( cp, "volatile" ) ) != NULL; ++cp )
  67.         if ( cp == s || ! isid( *( cp - 1 ) ) )
  68.             if ( ! isid( *( cp + 8 ) ) )
  69.             {
  70.                 for ( ep = cp + 8; *ep; ++ep )
  71.                     if ( ! isspace( *ep ) )
  72.                         break;
  73.                 strcpy( cp, ep );
  74.             }
  75. }
  76. /*-------------------------------------------------------------------------
  77. enumeration( s ) translates enumeration variables into #defines and ints.
  78. -------------------------------------------------------------------------*/
  79. PRIVATE enumeration( fo, s )
  80. FILE *fo;
  81. char *s;
  82. {
  83.     char *ekw, *end, *mem, *memend, *var;
  84.     char *p, *p2, name[ 80 ], *strchr(), *strstr();
  85.     int n;
  86.  
  87.     /* find "enum" keyword */
  88.     ekw = strstr( s, "enum" );
  89.  
  90.     /* find equal sign, semicolon, or end of line */
  91.     /* (ignore equal signs within member list, tho...) */
  92.     for ( end = ekw + 5; *end; ++end )
  93.         if ( *end == '{' )
  94.         {
  95.             /* member list, bypass it */
  96.             for ( ++end; *end; ++end )
  97.                 if ( *end == '}' )
  98.                     break;
  99.             if ( *end == '\0' )
  100.             {
  101.                 /* we only handle one-liner's */
  102.                 warning( "Multi-line enum not converted" );
  103.                 return;
  104.             }
  105.         }
  106.         else if ( *end == '=' )
  107.             break;
  108.         else if ( *end == ';' )
  109.             break;
  110.  
  111.     /* find any list of member definitions */
  112.     for ( mem = ekw + 5; mem < end; ++mem )
  113.         if ( *mem == '{' )
  114.             break;
  115.     if ( mem < end )
  116.     {
  117.         for ( memend = mem + 1; memend < end; ++memend )
  118.             if ( *memend == '}' )
  119.                 break;
  120.         if ( memend >= end )
  121.         {
  122.             /* we only handle one-liner's */
  123.             warning( "Multi-line enum not converted" );
  124.             return;
  125.         }
  126.     }
  127.     else mem = memend = NULL;
  128.  
  129.     /* output any member names as #defines */
  130.     if ( mem && memend )
  131.     {
  132.         for ( p = mem + 1, n = 0; p < memend; ++n )
  133.         {
  134.             /* bypass spaces */
  135.             while ( p < memend && ! isid( *p ) )
  136.                 ++p;
  137.             if ( p < memend )
  138.             {
  139.                 /* get enum member name into name[] */
  140.                 for ( p2 = name; p < memend && isid( *p ); )
  141.                     *p2++ = *p++;
  142.                 *p2 = '\0';
  143.                 /* position to end of name, handle '=' if found */
  144.                 for ( ; p < memend && *p != ','; ++p )
  145.                     if ( *p == '=' )
  146.                     {
  147.                         ++p;
  148.                         while ( p < memend && isspace( *p ) )
  149.                             ++p;
  150.                         if ( isdigit( *p ) )
  151.                             n = atoi( p );
  152.                     }
  153.                 if ( p < memend )
  154.                     ++p;
  155.                 /* output as #define */
  156.                 fprintf( fo, "#define %s %d\n", name, n );
  157.             }
  158.         }
  159.     }
  160.  
  161.     /* find any variable or typedef name */
  162.     if ( memend )
  163.     {
  164.         /* comes right after member list */
  165.         var = memend + 1;
  166.     }
  167.     else
  168.     {
  169.         /* bypass tag (should be there if no member list) */
  170.         var = ekw + 5;
  171.         /* bypass spaces */
  172.         while ( var < end && ! isid( *var ) )
  173.             ++var;
  174.         /* bypass tag */
  175.         while ( var < end && isid( *var ) )
  176.             ++var;
  177.     }
  178.     /* bypass spaces before variable or typedef name */
  179.     while ( var < end && ! isid( *var ) )
  180.         ++var;
  181.  
  182.     /* if variable or typedef name, make "enum [tag]" into "int" */
  183.     if ( var < end )
  184.     {
  185.         strcpy( ekw, "int " );
  186.         strcat( s, var );
  187.     }
  188.     /* else clear out line */
  189.     else *s = '\0';
  190. }
  191. /*-------------------------------------------------------------------------
  192. fplist( s, v ) looks to see if the "void" at v is a void function parameter
  193. list. If so, return TRUE, else FALSE.
  194. -------------------------------------------------------------------------*/
  195. PRIVATE int fplist( s, v )
  196. char *s, *v;
  197. {
  198.     char *pc, *sc;
  199.  
  200.     if ( v > s )
  201.     {
  202.         /* find first previous non-space char */
  203.         for ( pc = v - 1; pc > s; --pc )
  204.             if ( ! isspace( *pc ) )
  205.                 break;
  206.  
  207.         /* find first subsequent non-space char */
  208.         for ( sc = v + 4; *sc; ++sc )
  209.             if ( ! isspace( *sc ) )
  210.                 break;
  211.  
  212.         /* do we have empty parens? */
  213.         /* this also detects (void)i - wrong but hopefully uncommon */
  214.         if ( *pc == '(' && *sc == ')' )
  215.             return( TRUE );
  216.     }
  217.     return( FALSE );
  218. }
  219. /*=======================================================================*/
  220.